package cn.iocoder.yudao.module.system.controller.admin.cp.util;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author pg
 * @project zysx
 * @description 计算请假时间
 * @date 2024/9/3 10:36:31
 */
public class LeaveTimeSplitter {
    // 工作时间定义
    private static final LocalTime MORNING_START = LocalTime.of(9, 0);
    private static final LocalTime MORNING_END = LocalTime.of(12, 30);
    private static final LocalTime AFTERNOON_START = LocalTime.of(14, 30);
    private static final LocalTime AFTERNOON_END = LocalTime.of(18, 30);

    public static void main(String[] args) {
        // 输入的请假时间
        String start = "2024-08-01 10:00";
        String end = "2024-08-05 15:00";


        // 计算请假时间段
        List<LeaveTimeDetail> leavePeriods = calculateLeave(start, end, "请假");

        // 转成按日期分类的MAP
        Map<String, List<LeaveTimeDetail>> leaveMap = new HashMap<>();
        for (LeaveTimeDetail leave : leavePeriods) {
            String date = leave.getCurrentDate();
            List<LeaveTimeDetail> dateLeaves = leaveMap.getOrDefault(date, new ArrayList<>());
            dateLeaves.add(leave);
            leaveMap.put(date, dateLeaves);
        }

        // 输出结果
        for (LeaveTimeDetail leave : leavePeriods) {
            System.out.println("类型：" + leave.getType() + "，日期：" + leave.getCurrentDate() + "，开始时间：" + leave.getStartTime() + "，结束时间：" + leave.getEndTime() + "，请假时长：" + leave.getDuration());
        }
    }

    public static List<LeaveTimeDetail> calculateLeave(String start, String end, String type) {
        // 转换为LocalDateTime
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        LocalDateTime startDateTime = LocalDateTime.parse(start, formatter);
        LocalDateTime endDateTime = LocalDateTime.parse(end, formatter);
        // 计算请假时间段
        return calculateLeavePeriods(startDateTime, endDateTime, type);
    }

    private static List<LeaveTimeDetail> calculateLeavePeriods(LocalDateTime startDateTime, LocalDateTime endDateTime, String type) {
        List<LeaveTimeDetail> leaves = new ArrayList<>();
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");

        LocalDate currentDate = startDateTime.toLocalDate();

        // 遍历从开始日期到结束日期的每一天
        while (!currentDate.isAfter(endDateTime.toLocalDate())) {
            LocalTime dayStart;
            LocalTime dayEnd;

            // 如果是开始日期
            if (currentDate.isEqual(startDateTime.toLocalDate())) {
                dayStart = startDateTime.toLocalTime().isBefore(MORNING_START)? MORNING_START : startDateTime.toLocalTime();
                dayEnd = AFTERNOON_END;  // 最晚为18:30
                if (endDateTime.toLocalDate().isEqual(currentDate)) {
                    dayEnd = endDateTime.toLocalTime().isBefore(AFTERNOON_END) ? endDateTime.toLocalTime() : AFTERNOON_END;
                }
            } else if (currentDate.isEqual(endDateTime.toLocalDate())) {
                // 如果是结束日期
                dayStart = MORNING_START;
                dayEnd = endDateTime.toLocalTime().isAfter(AFTERNOON_END) ? AFTERNOON_END : endDateTime.toLocalTime();
            } else {
                // 中间的整天
                dayStart = MORNING_START;
                dayEnd = AFTERNOON_END;
            }

            // 计算请假时长
            double leaveHours = calculateLeaveHours(dayStart, dayEnd);

            // 添加到列表
            leaves.add(new LeaveTimeDetail(type, currentDate.format(dateFormatter), dayStart.format(timeFormatter), dayEnd.format(timeFormatter), String.valueOf(leaveHours)));
            // 处理下一天
            currentDate = currentDate.plusDays(1);
        }

        return leaves;
    }

    private static double calculateLeaveHours(LocalTime start, LocalTime end) {
        double leaveHours = 0.0;

        // 如果在上午时间段内
        if (start.isBefore(MORNING_END) && end.isAfter(MORNING_START)) {
            LocalTime morningEnd = end.isBefore(MORNING_END) ? end : MORNING_END;
            leaveHours += Duration.between(start.isBefore(MORNING_START) ? MORNING_START : start, morningEnd).toMinutes() / 60.0;
        }

        // 如果在下午时间段内
        if (start.isBefore(AFTERNOON_END) && end.isAfter(AFTERNOON_START)) {
            LocalTime afternoonStart = start.isAfter(AFTERNOON_START) ? start : AFTERNOON_START;
            leaveHours += Duration.between(afternoonStart, end.isAfter(AFTERNOON_END) ? AFTERNOON_END : end).toMinutes() / 60.0;
        }

        // 按半小时向上取整
        return Math.ceil(leaveHours * 2) / 2.0;
    }
}
